package com.zf.easyexcel.utils;

import com.zf.easyexcel.entity.SheetMergeInfo;
import org.apache.commons.collections4.MapUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;

/**
 * 合并工具
 */
public class ExcelMergeUtils {
    /**
     * 计算多行单元格的合并信息，
     * 注意：最好对数据分组后，再每一组都调用该方法，防止因不同分组连接处的数据相同造成的跨分组误合并，最后将所有的计算结果汇总即可
     *
     * @param dataList   数据
     * @param fieldList  需要计算合并信息的列名
     * @param startIndex 开始行的位置索引
     */
    public static List<SheetMergeInfo> calRowCellMergeInfo(List<LinkedHashMap<String, Object>> dataList, List<String> fieldList, int startIndex) {
        ArrayList<SheetMergeInfo> res = new ArrayList<>();
        // 遍历处理每一列
        for (String fieldName : fieldList) {
            // 遍历时重置 startIndex
            int tempStartIndex = startIndex;
            // 相邻的相同项的数量
            int count = 1;
            // 标准值
            String standardValue = MapUtils.getString(dataList.get(0), fieldName, "");
            int size = dataList.size();
            for (int i = 1; i < size; i++) {
                LinkedHashMap<String, Object> map = dataList.get(i);
                String cmpValue = MapUtils.getString(map, fieldName, "");
                if (!Objects.equals(standardValue, cmpValue)) {
                    // 不相同，则合并前面的相同项
                    // 相同项 > 1 的才合并
                    if (count > 1) {
                        res.add(new SheetMergeInfo(fieldName, tempStartIndex, tempStartIndex + count - 1, standardValue));
                    }
                    // 重置
                    tempStartIndex += count;
                    standardValue = cmpValue;
                    count = 1;
                } else if (i == size - 1) {
                    // 相同且到最后
                    //则将合并的结束行置成末尾行所在的索引
                    res.add(new SheetMergeInfo(fieldName, tempStartIndex, tempStartIndex + count, standardValue));
                } else {
                    // 相同但是不是最后一条，则+1
                    count++;
                }
            }
        }
        return res;
    }
}
